#coding=utf-8

import os
import urllib.request
import sys
import socket
import base64
from urllib.parse import quote
import requests
from contextlib import closing

#下载进度显示
class DownloadDisplay:
	
	def __init__(self):
		self.downloadPath = ""
		self.isoName = ""
		self.value = 0
	
	def SetDownloadPath(self,downloadPath):
		self.downloadPath = downloadPath

	def SetISOName(self,isoName):
		self.isoName = isoName

	#下载进度更新
	def UpdateValue(self,block_size,total_size):
		percent = block_size/total_size*100
		self.value = int(percent)
		#sys.stdout.write("\r%d%%" % percent + ' complete')
		#sys.stdout.flush()

def is_chinese(uchar):
	if uchar >= '\u2E80' and uchar <= '\uFe4F':
		return True
	else:
		return False

class HttpTool:
	#获取网页内容
	def FetchUrlData(self,url,decoding):
		try:
			headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36'}
			req = urllib.request.Request(url=url, headers=headers)
			html = urllib.request.urlopen(req,timeout=50).read()
			html = html.decode(decoding,'ignore')
			return html
		except urllib.error.HTTPError as e:
			print(e.code)
		except urllib.error.URLError as e:
			print(e.reason)
		except socket.timeout:
			print("socket timeout")	

	#迅雷下载地址转换真实下载地址
	def thunder2Real(self,url): 
		THUNDER_HEADER = "thunder://"  
		THUNDER_PREFIX = "AA"  
		THUNDER_SUFFIX = "ZZ"  
		url = url[len("thunder://"):]  
		url = base64.b64decode(url.encode("utf-8"))  
		url = url.decode("utf-8")  
		url = url[len("AA"):-len("ZZ")]  
		return url 
	
	#真实下载地址转换迅雷下载地址
	def real2Thunder(self,url):  
		url = "AA" + url + "ZZ"  
		url = base64.b64encode(url.encode("utf-8"))  
		url = "thunder://" + url.decode("utf-8")  
		return url

	#真实下载地址转换QQ旋风下载地址
	def real2QQ(url):  
		url = base64.b64encode(url.encode("utf-8"))  
		url = "qqdl://" + url.decode("utf-8")  
		return url  
 
 	#QQ旋风下载地址转换真实下载地址
	def qq2Real(url):  
		url = url[len("qqdl://"):]  
		url = base64.b64decode(url.encode("utf-8"))  
		url = url.decode("utf-8")  
		return url

	#下载文件
	def DownLoad(self,url,downloadPath,downloadDisplay,excelTool):
		try:	
			#URL处理可能有中文的链接
			newUrl = str()
			for c in url:
				if is_chinese(c):
					c = quote(c)
				newUrl += c
			#确认链接可否打开
			headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36'}
			req = urllib.request.Request(url=newUrl, headers=headers)
			res = urllib.request.urlopen(req,timeout=50)
			if not res:
				return False
			
			filename = res.geturl().split('/')[-1]#下载文件真实名称
			content_size = int(res.headers['content-length'])#文件大小(BYTE)
			#sys.stdout.write("\r当前下载路径:" + url + "\n")
			#sys.stdout.write("\r当前下载镜像:" + filename + '\n')
			downloadDisplay.SetDownloadPath(url)
			downloadDisplay.SetISOName(filename)
			excelTool.SetFilename(filename)
			#下载文件更改后缀名作为临时文件，下载完成改回原文件名
			file_temp = downloadPath + filename + ".tmp"
			#判断文件是否存在，不存在则重新下载，存在则继续下载
			#重新下载
			if not os.path.exists(file_temp):
				with closing(requests.get(newUrl, stream = True)) as response:
					chunk_size = 1024#单次请求最大值
					#content_size = int(response.headers['content-length'])#内容体总大小
					block_size = 0#当前下载大小	
					with open(file_temp, "wb") as File:
						for data in response.iter_content(chunk_size = chunk_size):
							File.write(data)
							block_size += len(data)
							downloadDisplay.UpdateValue(block_size,content_size)
			#断点续传
			else:
				block_size = os.path.getsize(file_temp)#当前下载大小
				headers = {'Range': 'bytes=%d-' %block_size}
				chunk_size = 1024#单次请求最大值
				#rest_size = content_size - block_size
				#chunk_size = min(1024, rest_size)		
				with closing(requests.get(newUrl, stream = True, headers = headers)) as response:
					with open(file_temp, "ab") as File:
						for data in response.iter_content(chunk_size = chunk_size):
							File.write(data)
							block_size += len(data)
							downloadDisplay.UpdateValue(block_size,content_size)
			os.rename(file_temp, downloadPath + filename)
			return True
		except urllib.error.HTTPError as e:
			print(e.code)
			return False
		except urllib.error.URLError as e:
			print(e.reason)
			return False
		except socket.timeout:
			print("socket timeout")
			return False
		#except urllib.ContentTooShortError:
			#print('Network conditions is not good.Reloading.')
			#os.remove(downloadPath + filename + ".tmp")
			#DownLoad(url,filename)

httpTool = HttpTool()
